package com.cooper.moviedb.servers;

import com.cooper.moviedb.bo.DeleteMedia;
import com.cooper.moviedb.bo.MediaEntity;
import com.cooper.moviedb.bo.MediaInfoEntity;
import com.cooper.moviedb.bo.MediaUriEntity;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: cooperlee
 * Date: 11/27/12
 * Time: 10:13 AM
 */
public class MovieOut {

    private static final int PAGE_COUNT = 20;

    private Set<String> deleteUrl = new HashSet<String>();

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    private void initDeleteUrl() {
        deleteUrl.clear();
        Session session = sessionFactory.openSession();
        try {
            deleteUrl.addAll(session.createQuery("select url from DeleteMedia").list());
        } finally {
            session.close();
        }
    }

    private void validMedia(MediaEntity media) {
        for (MediaUriEntity mediaUrl : media.getMediaUriEntitySet()) {
            if (deleteUrl.contains(mediaUrl.getUrl())) {
                mediaUrl.setDeleted(true);
            }
        }
        boolean delete = true;
        for (MediaUriEntity mediaUrl : media.getMediaUriEntitySet()) {
            if (!mediaUrl.isDeleted()) {
                delete = false;
                break;
            }
        }
        media.setDeleted(delete);

    }

    private SessionFactory sessionFactory;

    private void outXml(List<MediaEntity> datas, int page, Session session, String outDir, String detailsDirName) {


        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("movies");

        for (int i = datas.size() - 1; i >= 0; i--) {
            MediaEntity data = datas.get(i);

            validMedia(data);
            if (!data.isDeleted()) {

                Element movieElement = root.addElement("movie");
                movieElement.addAttribute("id", data.getId());
                movieElement.addElement("details_url").addText(detailsDirName + page + ".xml");
                for (MediaInfoEntity mediaInfoEntity : data.getMediaInfoEntitySet()) {
                    if (!mediaInfoEntity.getKeyName().equals("play") && !mediaInfoEntity.getKeyName().equals("details_url")) {
                        movieElement.addElement(mediaInfoEntity.getKeyName()).addText(mediaInfoEntity.getValue());
                    }
                }
                for (MediaUriEntity mediaUriEntity : data.getMediaUriEntitySet()) {
                    if (!mediaUriEntity.isDeleted()) {
                        movieElement.addElement("play").addText(mediaUriEntity.getUrl());
                    }
                }


                if (data.getPage() != page) {
                    data.setPage(page);
                    Transaction tx = session.beginTransaction();
                    session.update(data);
                    tx.commit();
                }
            }
        }
        try {
            FileWriter out = new FileWriter(outDir + page + ".xml");
            document.write(out);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    public void updateOutPages(String outDir, String detailsDirName) {

        initDeleteUrl();
        Session session = sessionFactory.openSession();
        try {
            int maxPage = ((Integer) session.createQuery("select max(page) from MediaEntity").iterate().next()).intValue();
            System.out.println("====max page is:" + maxPage);
            Query query = session.createQuery("from MediaEntity where deleted <> true and page=? order by joinTime ");
            for (int i = 1; i <= maxPage; i++) {
                query.setInteger(0, i);
                List<MediaEntity> pageData = query.list();
                outXml(pageData, i, session, outDir, detailsDirName);
            }

            int count = ((Long) session.createQuery("select count(id) from MediaEntity where deleted <> true and page <= 0").iterate().next()).intValue();
            System.out.println("====new count is:" + count);
            if (count > 0) {
                query = session.createQuery("from MediaEntity where deleted <> true and (page=? or page <=0) order by joinTime").setInteger(0, maxPage);

                List<MediaEntity> pageData;
                int page = maxPage;
                int recordIndex = 0;
                query.setFirstResult(recordIndex);
                query.setMaxResults(PAGE_COUNT);
                pageData = query.list();


                while (!pageData.isEmpty()) {
                    outXml(pageData, page, session, outDir, detailsDirName);

                    page++;
                    recordIndex += PAGE_COUNT;
                    query.setFirstResult(recordIndex);
                    pageData = query.list();
                }

            }

        } finally {
            session.close();
        }
    }

    public void initOutPages(String outDir, String detailsDirName) {
        initDeleteUrl();
        File outDirF = new File(outDir);
        if (!outDirF.exists()) {
            outDirF.mkdirs();
        }

        Session session = sessionFactory.openSession();
        try {
            Query q = session.createQuery("from MediaEntity where deleted <> true order by joinTime");
            List<MediaEntity> pageData;
            int page = 1;
            int recordIndex = 0;
            q.setFirstResult(recordIndex);
            q.setMaxResults(PAGE_COUNT);
            pageData = q.list();
            while (!pageData.isEmpty()) {
                outXml(pageData, page, session, outDir, detailsDirName);

                page++;
                recordIndex += PAGE_COUNT;
                q.setFirstResult(recordIndex);
                pageData = q.list();
            }

        } finally {
            session.close();
        }
    }

    public void addDeleteMedia(String url) {
        Session session = sessionFactory.openSession();
        try {
            Transaction tx = session.beginTransaction();
            session.save(new DeleteMedia(url));

            tx.commit();
        } finally {
            session.close();
        }
    }

    public void addUrl(String movieId, String url) {
        Session session = sessionFactory.openSession();
        try {
            MediaEntity media = (MediaEntity) session.get(MediaEntity.class, movieId);
            if (media != null) {
                media.getMediaUriEntitySet().add(new MediaUriEntity(media, url, new Timestamp(new Date().getTime()), false));
                Transaction tx = session.beginTransaction();
                session.save(media);

                tx.commit();
            }
        } finally {
            session.close();
        }

    }
}
